package com.atguigu.gmall.realtime.function;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.realtime.util.DimUtil;
import com.atguigu.gmall.realtime.util.JdbcUtil;
import com.atguigu.gmall.realtime.util.RedisUtil;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.configuration.Configuration;
import redis.clients.jedis.Jedis;

import java.sql.Connection;

/**
 * @Author lzc
 * @Date 2023/2/21 08:45
 */
public abstract class DimFunctionWithCache<T> extends RichMapFunction<T, T> {
    
    private Connection conn;
    private Jedis redisClient;
    
    @Override
    public void open(Configuration parameters) throws Exception {
        conn = JdbcUtil.getPhoenixConnection();
        
        redisClient = RedisUtil.getRedisClient();
    }
    
    @Override
    public void close() throws Exception {
        JdbcUtil.closeConnection(conn);
        // 1. 如果客户端是通过 new Jedis()得到的, 则是直接关闭
        // 2. 如果是通过连接池得到, 则是归还给连接池
        redisClient.close();
        
    }
    
    public abstract String getTable();
    
    public abstract Object getId(T value);
    
    public abstract void addDim(T value, JSONObject dim);
    
    @Override
    public T map(T value) throws Exception {
        // 1. 从 phoenix 读取 dim 数据
       //JSONObject dim = DimUtil.readDimFromPhoenix(conn, getTable(), getId(value));
       JSONObject dim = DimUtil.readDim(redisClient, conn, getTable(), getId(value));
       
       
       // 2. 给 value 中的维度字段赋值
       addDim(value, dim);
       
        return value;
    }
}
/*
加缓冲
    把维度数据存储到内存中
    
1. 存入到 flink 的状态中
    dim_sku_info:1 => {...}
    
    优点:
        本地内存, 快
        数据结构丰富
    缺点:
        1. 占用 flink 的内存, 影响 flink 的计算
        2. 当维度发生变化的时候, 状态中的维度没有办法及时更新
2. redis(旁路缓存)
    优点:
         当维度发生变化的时候, 缓存中的维度可以办法及时更新
    
    缺点:
        需要通过网络读取, 效率受影响
        
数据在 redis 中如何存储?

string
    key                 value
    表名:id               {json 格式的字符串}
    dim_sku_info:1      {"id:":'',"spu_id": "", .... }
    
    优点:
        1.存取比较方便
        2.一条维度数据, 一个 key, 所以, 可以单独给每个维度设置 ttl
    缺点:
        key 比较多, 不方便管理.而且容易与其他的key 产生冲突
            redis 默认有 16 个库, 选择一个没人用的
        

list
    key                 value
    表名              [{}, {}, {}]
    
    dim_sku_info        [{}, {}, ...]
    
    优点:
        存比较方便 lpush rpush
        key 比较少, 方便管理
    缺点:
        取不方便: 每次需要读取一张的所有维度数据,然后再根据 id 进行遍历找到需要的维度, 效率比较低
        没有办法给每个维度单独设置 ttl
      

set
    相比 list, 多了去重

hash(map)
    
    key             field           value
    表名              id              {}
    dim_sku_info    1               {}
                    2               {}
                    
     优点:
        存取方便  hset(key, f, v)  hget(key, f)
        
        key 比较少, 一张一个 key, 方便管理
        
   缺点:
    没有办法给每个维度单独设置 ttl

zset
 
 



 */